# Copyright (C) 2015-2016  Nicola Spanti (RyDroid) <dev@nicola-spanti.info>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.


PROJECT_NAME=PlanetWars2dRT-core

# Folders and files
SRC_DIR=src
INC_DIR=include
INC_NAMESPACE_DIR=$(INC_DIR)/$(PROJECT_NAME)
RELEASE_DIR=release
DEBUG_DIR=debug
DOC_DIR=doc
DOXYFILE=etc/doxygen_configuration.ini

# Commands
CMAKE=cmake -Wdev
CPPCHECK=cppcheck --language=c --std=c99 --verbose --quiet --error-exitcode=1
SPLINT=splint +quiet -I$(INC_DIR) -booltype bool -fcnuse -varuse -compdef

# Package and archive
PACKAGE=$(PROJECT_NAME)
FILES_TO_BUILD=$(SRC_DIR)/ $(INC_DIR)/ tests/ CMakeLists.txt
FILES_TO_ARCHIVE=$(FILES_TO_BUILD) etc/ makefile \
	licenses/ *.md \
	.gitignore .editorconfig .dir-locals.el \
	.gitlab-ci.yml .travis.yml .magnum.yml


default: bin-release

all: bin-release doc default-archive


.PHONY: \
	default all \
	packages \
	check tests \
	tests-static tests-dynamic \
	tests-cppcheck tests-vera++ tests-splint \
	tests-check tests-check-debug tests-valgrind \
	bin bin-release bin-debug \
	static-libs check_static \
	read-doc-web read-doc-pdf doc doc-web doc-pdf \
	see-todo-comments \
	archives default-archive zip tar-gz tar-bz2 tar-xz 7z \
	clean clean-build clean-build-release clean-build-debug \
	clean-bin clean-externals \
	clean-python clean-profiling \
	clean-ide clean-qt-creator clean-codeblocks \
	clean-tmp clean-doc clean-latex clean-archives clean-git


packages: $(RELEASE_DIR)/Makefile
	cd $(RELEASE_DIR) && make package


check: tests

tests: tests-static tests-dynamic

tests-static: bin-release tests-cppcheck tests-vera++ tests-splint

tests-cppcheck:
	 $(CPPCHECK) --enable=warning,style $(SRC_DIR) $(INC_DIR)
	 $(CPPCHECK) --enable=warning,performance,portability tests

tests-splint:
	$(SPLINT) -type $(INC_NAMESPACE_DIR)/utils/color_rgb.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/command_line_interface.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/cstring_functions.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/observer.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/observers.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/position_2d_float.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/position_2d_generic.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/position_2d_uint.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/rectangle_generic.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/selection_2d_generic.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/size_2d_uint.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/statistics.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/utils/vector_generic.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/model/planet.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/model/player.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/model/players_info.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/model/ship.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/game.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/planet.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/planet_collision.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/planet_observer.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/planet_produce.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/planet_update.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/player.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/selection.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/ship.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/universe.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/universe_collisions.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/controller/universe_update.h
	$(SPLINT) $(INC_NAMESPACE_DIR)/specific/view/*
	$(SPLINT) -paramuse $(SRC_DIR)/specific/model/game_state*.c
	$(SPLINT) $(SRC_DIR)/specific/model/planet.c
	$(SPLINT) -exportlocal $(SRC_DIR)/specific/model/planet_life.c
	$(SPLINT) -exportlocal $(SRC_DIR)/specific/model/planet_position.c
	$(SPLINT) -exportlocal $(SRC_DIR)/specific/model/planet_size.c
	$(SPLINT) $(SRC_DIR)/specific/model/ship.c
	$(SPLINT) -exportlocal $(SRC_DIR)/specific/model/ship_life.c
	$(SPLINT) $(SRC_DIR)/specific/model/ship_move.c
	$(SPLINT) -exportlocal $(SRC_DIR)/specific/model/ship_size.c

tests-vera++:
	@chmod +x ./tools/vera++-tests.sh
	./tools/vera++-tests.sh $(SRC_DIR) $(INC_DIR)

tests-dynamic: tests-check tests-valgrind

tests-check: bin-release
	cd $(RELEASE_DIR) && make test

tests-check-debug: bin-debug
	cd $(DEBUG_DIR) && make test

tests-valgrind: bin-release
	valgrind --quiet --errors-for-leak-kinds=all \
		./release/bin/planet-wars-2d-rt-text \
		1>/dev/null


install: $(RELEASE_DIR)/Makefile
	cd $(RELEASE_DIR) && make install


bin: bin-release bin-debug

bin-release: $(RELEASE_DIR)/Makefile
	cd $(RELEASE_DIR) && make

$(RELEASE_DIR)/Makefile: $(FILES_TO_BUILD)
	@mkdir -p $(RELEASE_DIR)
	cd $(RELEASE_DIR) && $(CMAKE) -DCMAKE_BUILD_TYPE=release ..

bin-debug: $(DEBUG_DIR)/Makefile
	cd $(DEBUG_DIR) && make

$(DEBUG_DIR)/Makefile: $(FILES_TO_BUILD)
	@mkdir -p $(DEBUG_DIR)
	cd $(DEBUG_DIR) && $(CMAKE) -DCMAKE_BUILD_TYPE=debug ..


static-libs: check_static

check_static:
	git submodule init   externals/check
	git submodule update externals/check
	cd externals/check && mkdir -p build && cd build && cmake .. && make
	echo '#include <stdint.h>' > externals/check/build/check_stdint.h


read-doc-web: doc-web
	xdg-open $(DOC_DIR)/html/index.html &

read-doc-pdf: doc-pdf
	xdg-open $(DOC_DIR)/latex/refman.pdf &

doc: doc-web doc-pdf

pdf: doc-pdf

doc-pdf: doc-web
	cd $(DOC_DIR)/latex/ && make

html: doc-web

doc-web: $(INC_DIR) $(DOXYFILE)
	doxygen $(DOXYFILE)


see-todo-comments:
	@grep --color=auto -rn TODO src/


archives: zip tar-gz tar-bz2 tar-xz 7z

dist: default-archive

default-archive: tar-xz

zip: $(PACKAGE).zip

$(PACKAGE).zip: $(FILES_TO_ARCHIVE)
	zip $(PACKAGE).zip -r -- $(FILES_TO_ARCHIVE)

tar-gz: $(PACKAGE).tar.gz

$(PACKAGE).tar.gz: $(FILES_TO_ARCHIVE)
	tar -zcvf $(PACKAGE).tar.gz -- $(FILES_TO_ARCHIVE)

tar-bz2: $(PACKAGE).tar.bz2

$(PACKAGE).tar.bz2: $(FILES_TO_ARCHIVE)
	tar -jcvf $(PACKAGE).tar.bz2 -- $(FILES_TO_ARCHIVE)

tar-xz: $(PACKAGE).tar.xz

$(PACKAGE).tar.xz: $(FILES_TO_ARCHIVE)
	tar -cJvf $(PACKAGE).tar.xz -- $(FILES_TO_ARCHIVE)

7z: $(PACKAGE).7z

$(PACKAGE).7z: $(FILES_TO_ARCHIVE)
	7z a -t7z $(PACKAGE).7z $(FILES_TO_ARCHIVE)


clean: \
	clean-build clean-externals clean-bin \
	clean-python clean-profiling clean-ide \
	clean-tmp clean-doc clean-latex clean-archives

clean-build: clean-build-release clean-build-debug
	@$(RM) -rf -- build/ Build/ builds/ Builds/

clean-build-release:
	@$(RM) -rf -- release/ Release/ $(RELEASE_DIR)/

clean-build-debug:
	@$(RM) -rf -- dbg/ debug/ Debug/ $(DEBUG_DIR)/

clean-externals:
	git submodule update

clean-bin:
	$(RM) -rf -- *.o *.a *.so *.ko *.lo *.dll *.out bin/

clean-python:
	$(RM) -rf -- *.pyc __pycache__

clean-profiling:
	$(RM) -rf -- callgrind.out.*

clean-ide: clean-qt-creator clean-codeblocks

clean-qt-creator:
	$(RM) -f -- qmake_makefile *.pro.user

clean-codeblocks:
	$(RM) -f -- *.cbp

clean-tmp:
	$(RM) -r -- \
		*~ *.bak *.backup .\#* \#* *.sav *.save *.autosav *.autosave \
		*.log *.log.* error_log* \
		.cache/ .thumbnails/

clean-doc:
	@$(RM) -rf -- doc/ Doc/ docs/ Docs/ documentation/ Documentation/

clean-latex:
	$(RM) -f -- \
		*.pdf *.dvi *.ps \
		*.acn *.aux *.bcf *.cut *.fls *.glo *.ist *.lof *.nav \
		*.run.xml *.snm *.toc *.vrb *.vrm *.xdy \
		*.fdb_latexmk *-converted-to.* \
		*.synctex *.synctex.gz *.synctex.bz2 *.synctex.xz \
		*.synctex.zip *.synctex.rar

clean-archives:
	$(RM) -rf -- \
		*.deb *.rpm *.exe *.msi *.dmg *.apk *.ipa \
		*.zip *.tar.* *.tgz *.7z *.gz *.bz2 *.lz *.lzma *.xz *.rar *.jar

clean-git:
	git clean -fdx
